import { ExceptionFilter, HttpException, HttpStatus, LoggerService, Query } from '@nestjs/common'
import { ArgumentsHost, Catch } from '@nestjs/common'
import { HttpAdapterHost } from '@nestjs/core'
import { Response } from 'express' // 导入 Express 的 Response 类型
import { Request } from 'express' // 导入 Express 的 Request 类型
import * as requestIp from 'request-ip'
import { QueryFailedError } from 'typeorm'

@Catch()
export class AllExceptionFilter implements ExceptionFilter {
  constructor(
    private readonly logger: LoggerService,
    private readonly httpAdapterHost: HttpAdapterHost
  ) {}
  catch(exception: unknown, host: ArgumentsHost) {
    const { httpAdapter } = this.httpAdapterHost
    const ctx = host.switchToHttp()
    const request = ctx.getRequest<Request>()
    const response = ctx.getResponse<Response>()

    const httpStatus =
      exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR

    const msg: string = (exception as { response: string })['response'] || 'Internal Server Error' // 强制转换类型
    // 加入更多异常错误逻辑
    // if (exception instanceof QueryFailedError) {
    //   //QueryFailedError：数据库查询错误,扩展了typeorm，instanceof：检测是否为某个类的实例
    //   msg = exception.message
    //   // if (exception.driverError.errno && exception.driverError.errno === 1062) {
    //   //   msg = '数据唯一键冲突，请修改后重新添加'
    //   // }
    // }
    const responseBody = {
      headers: request.headers,
      query: request.query,
      body: request.body as object,
      params: request.params,
      timestamp: new Date().toISOString(),
      ip: requestIp.getClientIp(request) || 'unknown',
      exception: (exception as { name: string })['name'], // 强制转换类型
      error: msg
    }

    this.logger.error('[toimc]', responseBody)
    httpAdapter.reply(response, responseBody, httpStatus)
  }
}
